﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace GameHighlights
{
    public partial class frmMain : Form
    {
        #region Constructor
        public frmMain()
        {
            #region Splash Screen
            Thread t = new Thread(new ThreadStart(ShowSplashScreen));
            t.Start();
            Thread.Sleep(2000);
            t.Abort();
            #endregion
            InitializeComponent();
        }
        #endregion

        public void ShowSplashScreen()
        {
            Application.Run(new SplashScreen());
        }

        #region Declarations
        string PanelClick = string.Empty;
        string Highlights = string.Empty;
        bool firstTime = false;
        int gameLevel = 1;
        Circle blueCircle;
        Circle RedCircle;
        Circle YellowCircle;
        Circle orangeCircle;
        Circle BlackCircle;
        int oldRandVal = 0;
        int randomVal = 0;
        int clickCounts = 0;
        bool clickAllowed = false;
        #endregion

        #region Methods
        private void GameProcess(int gameLevel)
        {
            DisposeCircles(out blueCircle, out RedCircle, out YellowCircle, out orangeCircle, out BlackCircle);
            InstantiateCircles(out blueCircle, out RedCircle, out YellowCircle, out orangeCircle, out BlackCircle);

            for (int i = 0; i < gameLevel; i++)
			{
                Random rand = new Random();
                Circle[] allCirlces = { blueCircle, RedCircle, BlackCircle, orangeCircle, YellowCircle };
                //randomVal = rand.Next(0, 5);
                do
                {
                    randomVal = rand.Next(0, 5);

                } while (oldRandVal==randomVal);
                oldRandVal = randomVal;
                label1.Text = Highlights += randomVal.ToString();
                Circle currentCircle = returnRandomCircle(allCirlces, randomVal);
                DrawAnimateCircle(currentCircle.ThisPanel.CreateGraphics(), currentCircle);
			}
            
        }

        private void DisposeCircles(out Circle blueCircle, out Circle RedCircle, out Circle YellowCircle, out Circle orangeCircle, out Circle BlackCircle)
        {
            blueCircle = null; RedCircle = null; YellowCircle = null; orangeCircle = null; BlackCircle = null;
        }

        private void InstantiateCircles(out Circle blueCircle, out Circle RedCircle, out Circle YellowCircle, out Circle orangeCircle, out Circle BlackCircle)
        {
            blueCircle = new Circle(40, 22, 50, 50, new SolidBrush(Color.Blue), panel1, 0);
            RedCircle = new Circle(40, 22, 50, 50, new SolidBrush(Color.Red), panel2, 1);
            YellowCircle = new Circle(40, 22, 50, 50, new SolidBrush(Color.Green), panel3, 2);
            orangeCircle = new Circle(40, 22, 50, 50, new SolidBrush(Color.DarkOrange), panel4, 3);
            BlackCircle = new Circle(40, 22, 50, 50, new SolidBrush(Color.Black), panel5, 4);
        }

        private void resetGame()
        {
            lblGameLevel.Text = label1.Text = Highlights = PanelClick = "";
            gameLevel = clickCounts= 1;
            firstTime = true;
            DisposeCircles(out blueCircle, out RedCircle, out YellowCircle, out orangeCircle, out BlackCircle);
            RemovePanelMouseUpEvents();
            RemovePaintEvents();
            btnStart.Enabled = true;
            clickAllowed = false;
            //btnCalculate.Enabled = false;
            //setButton(btnStart);
        }

       //Depreciated
        private void setButton(Button currentButton)
        {
            currentButton.Enabled = true;
            currentButton.Focus();
            this.AcceptButton = currentButton;
        }

        private void NextLevelSettings()
        {
            label1.Text = Highlights = PanelClick = "";
        }

        private void DrawAnimateCircle(Graphics graphics, Circle c)
        {
            int count = 0;
            c.ThisPanel.Refresh();
            //increasing the size
            for (int i = 1; i <= 10; i++)
            {
                graphics.FillEllipse(c.CircleBrush, c.X + i, c.Y + i, c.Width + i, c.Height + i);
                Thread.Sleep(50);
                if (i != 10)
                {
                    c.ThisPanel.Refresh();
                }
                count++;
            }
            c.X += count;
            c.Y += count;
            c.Width += count;
            c.Height += count;
            count = 0;
            //decreasing the size
            for (int j = 1; j <= 10; j++)
            {
                if (j != 10)
                    c.ThisPanel.Refresh();
                graphics.FillEllipse(c.CircleBrush, c.X - j, c.Y - j, c.Width - j, c.Height - j);
                Thread.Sleep(50);
                count++;
            }
            c.X -= count;
            c.Y -= count;
            c.Width -= count;
            c.Height -= count;
         }

        private void DrawCircle(Graphics graphics, Circle c)
        {
            graphics.FillEllipse(c.CircleBrush, c.X, c.Y, c.Width, c.Height);
        }

        public Circle returnRandomCircle(Circle[] allCirlces, int randomNumber)
        {
            Circle result = (from c in allCirlces
                             where c.Number == randomNumber
                             select new Circle
                             {
                                 CircleBrush = c.CircleBrush,
                                 Height = c.Height,
                                 Width = c.Width,
                                 Number = c.Number,
                                 X = c.X,
                                 Y = c.Y,
                                 ThisPanel = c.ThisPanel
                             }).First();
            return result;
        }

        private void AddPaintEvents()
        {
            panel1.Paint += this.panel1_Paint;
            panel2.Paint += this.panel2_paint;
            panel3.Paint += this.panel3_Paint;
            panel4.Paint += this.panel4_paint;
            panel5.Paint += this.panel5_Paint;
        }

        private void RemovePaintEvents()
        {
            panel1.Paint -= this.panel1_Paint;
            panel2.Paint -= this.panel2_paint;
            panel3.Paint -= this.panel3_Paint;
            panel4.Paint -= this.panel4_paint;
            panel5.Paint -= this.panel5_Paint;
        }

        private void AddPanelMouseUpEvents()
        {
            this.panel1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseUp);
            this.panel2.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panel2_MouseUp);
            this.panel3.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panel3_MouseUp);
            this.panel4.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panel4_MouseUp);
            this.panel5.MouseUp += new System.Windows.Forms.MouseEventHandler(this.panel5_MouseUp);
            clickAllowed = true;
        }

        private void RemovePanelMouseUpEvents()
        {
            this.panel1.MouseUp -= new System.Windows.Forms.MouseEventHandler(this.panel1_MouseUp);
            this.panel2.MouseUp -= new System.Windows.Forms.MouseEventHandler(this.panel2_MouseUp);
            this.panel3.MouseUp -= new System.Windows.Forms.MouseEventHandler(this.panel3_MouseUp);
            this.panel4.MouseUp -= new System.Windows.Forms.MouseEventHandler(this.panel4_MouseUp);
            this.panel5.MouseUp -= new System.Windows.Forms.MouseEventHandler(this.panel5_MouseUp);
            clickAllowed = false;
        }

        #endregion

        #region Events

        private void Form1_Load(object sender, EventArgs e)
        {
            btnStart.Enabled = firstTime = true;
            lblGameLevel.Text = Constants.GameLevel+gameLevel.ToString();
            InstantiateCircles(out blueCircle, out RedCircle, out YellowCircle, out orangeCircle, out BlackCircle);
            AddPaintEvents();
        }       

        private void panel5_Paint(object sender, PaintEventArgs e)
        {
            if (firstTime)
            {
                DrawCircle(e.Graphics, BlackCircle);
            }
        }

        private void panel4_paint(object sender, PaintEventArgs e)
        {
            if (firstTime)
            {
                DrawCircle(e.Graphics, orangeCircle);
            }
        }

        private void panel3_Paint(object sender, PaintEventArgs e)
        {
            if (firstTime)
            {
                DrawCircle(e.Graphics, YellowCircle);
            }
        }

        private void panel2_paint(object sender, PaintEventArgs e)
        {
            if (firstTime)
            {
                DrawCircle(e.Graphics, RedCircle);
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            if (firstTime)
            {
                DrawCircle(e.Graphics, blueCircle);
            }
        }

        private void panel2_MouseUp(object sender, MouseEventArgs e)
        {
            if (clickAllowed)
            {
                if (clickCounts > 1)
                {
                    PanelClick += "1".ToString();
                    clickCounts--;
                }
                else
                {
                    PanelClick += "1".ToString();
                    CalculateResult();
                } 
            }
           
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if (clickAllowed)
            {
                if (clickCounts > 1)
                {
                    PanelClick += "0".ToString();
                    clickCounts--;
                }
                else
                {
                    PanelClick += "0".ToString();
                    CalculateResult();
                } 
            }
           
        }

        private void panel3_MouseUp(object sender, MouseEventArgs e)
        {
            if (clickAllowed)
            {
                if (clickCounts > 1)
                {
                    PanelClick += "2".ToString();
                    clickCounts--;
                }
                else
                {
                    PanelClick += "2".ToString();
                    CalculateResult();
                } 
            }
        }

        private void panel4_MouseUp(object sender, MouseEventArgs e)
        {
            if (clickAllowed)
            {
                if (clickCounts > 1)
                {
                    PanelClick += "3".ToString();
                    clickCounts--;
                }
                else
                {
                    PanelClick += "3".ToString();
                    CalculateResult();
                } 
            }
        }

        private void panel5_MouseUp(object sender, MouseEventArgs e)
        {
            if (clickAllowed)
            {
                if (clickCounts > 1)
                {
                    PanelClick += "4".ToString();
                    clickCounts--;
                }
                else
                {
                    PanelClick += "4".ToString();
                    CalculateResult();
                } 
            }
        }

        private void howToPlayToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmHowToPlay howtoPlay = new frmHowToPlay();
            howtoPlay.ShowDialog();
        }

        private void btnCalculate_Click(object sender, EventArgs e)
        {
            CalculateResult();
        }

        private void CalculateResult()
        {
            MyMessageBox MessageBox;
            MyMessageBoxIcon result = new MyMessageBoxIcon();
            if (Highlights.Equals(PanelClick))
            {
                if (gameLevel - 1 != 10)
                {
                    //MessageBox.Show(string.Format(Constants.CrossedLevelMessage,(gameLevel - 1).ToString()), Constants.CrossedLevelCaption, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                    MessageBox = new MyMessageBox(string.Format(Constants.CrossedLevelMessage, (gameLevel - 1).ToString()), Constants.CrossedLevelCaption, Enum.TryParse<MyMessageBoxIcon>((gameLevel-1).ToString(), out result) ? result: MyMessageBoxIcon.None);
                    MessageBox.ShowDialog();
                    Thread.Sleep(1500);
                    MessageBox.Dispose();
                    lblGameLevel.Text = "LeveL " + gameLevel;
                    lblGameLevel.Refresh();
                    StartGame();
                }
                else
                {
                    //MessageBox.Show(Constants.CrossedAllLevels, Constants.CrossedAllLevelCaption, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                    MessageBox = new MyMessageBox(Constants.CrossedAllLevels, Constants.CrossedAllLevelCaption, MyMessageBoxIcon.CrossedAllLevels);
                    MessageBox.ShowDialog();
                    MessageBox.Dispose();
                    lblGameLevel.Text = Constants.CrossedAllLevelCaption;
                    resetGame();
                }
            }
            else
            {
                switch (gameLevel - 1)
                {
                    case 1:
                        MessageBox = new MyMessageBox(Constants.FailedLevel1, Constants.CaptionFailedLevel + (gameLevel - 1).ToString(), MyMessageBoxIcon.FailedAtLevelOne);
                        MessageBox.ShowDialog();
                        MessageBox.Dispose();
                        break;
                    case 2:
                        MessageBox = new MyMessageBox(Constants.FailedLevel2, Constants.CaptionFailedLevel + (gameLevel - 1).ToString(), MyMessageBoxIcon.FailedAtLevelTwo);
                        MessageBox.ShowDialog();
                        MessageBox.Dispose();
                        break;
                    case 3:
                        MessageBox = new MyMessageBox(Constants.FailedLevel3, Constants.CaptionFailedLevel + (gameLevel - 1).ToString(), MyMessageBoxIcon.FailedAtLevelThree);
                        MessageBox.ShowDialog();
                        MessageBox.Dispose();
                        break;
                    case 4:
                        MessageBox = new MyMessageBox(Constants.FailedLevel4, Constants.CaptionFailedLevel + (gameLevel - 1).ToString(), MyMessageBoxIcon.FailedAtLevelFour);
                        MessageBox.ShowDialog();
                        MessageBox.Dispose();
                        break;
                    case 5:
                        MessageBox = new MyMessageBox(Constants.FailedLevel5, Constants.CaptionFailedLevel + (gameLevel - 1).ToString(), MyMessageBoxIcon.FailedAtLevelFive);
                        MessageBox.ShowDialog();
                        MessageBox.Dispose();
                        break;
                    case 6:
                        MessageBox = new MyMessageBox(Constants.FailedLevel6, Constants.CaptionFailedLevel + (gameLevel - 1).ToString(), MyMessageBoxIcon.FailedAtLevelSix);
                        MessageBox.ShowDialog();
                        MessageBox.Dispose();
                        break;
                    case 7:
                        MessageBox = new MyMessageBox(Constants.FailedLevel7, Constants.CaptionFailedLevel + (gameLevel - 1).ToString(), MyMessageBoxIcon.FailedAtLevelSeven);
                        MessageBox.ShowDialog();
                        MessageBox.Dispose();
                        break;
                    case 8:
                        MessageBox = new MyMessageBox(Constants.FailedLevel8, Constants.CaptionFailedLevel + (gameLevel - 1).ToString(), MyMessageBoxIcon.GreatGoingEight);
                        MessageBox.ShowDialog();
                        MessageBox.Dispose();
                        break;
                    case 9:
                        MessageBox = new MyMessageBox(Constants.FailedLevel9, Constants.CaptionFailedLevel + (gameLevel - 1).ToString(), MyMessageBoxIcon.FailedAtLevelNine);
                        MessageBox.ShowDialog();
                        MessageBox.Dispose();
                        break;
                    case 10:
                        MessageBox = new MyMessageBox(Constants.FailedLevel10, Constants.CaptionFailedLevel + (gameLevel - 1).ToString(), MyMessageBoxIcon.FailedAtLevelTen);
                        MessageBox.ShowDialog();
                        MessageBox.Dispose();
                        break;
                    default:
                        break;
                }
                resetGame();
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = false;
            StartGame();
        }

        private void StartGame()
        {
            PrepareForNextLevel();
            RemovePanelMouseUpEvents();
            firstTime = false;
            //NextLevelSettings();
            GameProcess(gameLevel);
            clickCounts = gameLevel; //controlling mouse click events (part of removing Calculate button)
            gameLevel++;
            btnStart.Enabled = false;
            //setButton(btnCalculate);
            AddPanelMouseUpEvents();
        }

        private void PrepareForNextLevel()
        {
            Highlights = string.Empty;
            PanelClick = string.Empty;
            label1.Text = string.Empty;
            //setButton(btnStart);
            //btnCalculate.Enabled = false;
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (gameLevel > 1)
            {
                DialogResult userChoice = MessageBox.Show(Constants.GameResetText, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
                if (userChoice == DialogResult.Yes)
                {
                    resetGame();
                }
            }
        }

        private void resetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            resetGame();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MyAboutBox aboutWindow = new MyAboutBox();
            aboutWindow.ShowDialog();
        }

        #endregion

        private void frmMain_Activated(object sender, EventArgs e)
        {
            firstTime = true;
        }
    }
}
